Early microprocessor based systems utilized a central processing unit, or CPU, which executed instructions, one at a time, in the order in which they were presented. These CPU's, due to their relative complexity, and associated cost, were typically designed to have universal application. That is, they were designed as general purpose CPU's.
As the use of general purpose CPU's increased, so did the variety of application programs they were required to execute. In some instances, certain programs ran extremely slow because they required the CPU to perform complex calculations that were really beyond the scope of what it was intended to perform. An example of such calculations included floating point operations, such a multiply, divide, etc.
To assist the CPU in executing such complex calculations, a floating point coprocessor was designed. The floating point coprocessor was essentially a second processor, external to the CPU, that was designed to perform certain complex operations such as a floating point multiply, a floating point divide, etc, albeit much faster than the CPU. In operation, the CPU, when it was asked to perform a complex operation, would pass the operation over to the floating point coprocessor. The coprocessor would complete the task, and pass the results back to the CPU.
Although the development of the floating point coprocessor enhanced the processing speed of certain applications, its cost kept it from being added to all systems. So, many computer systems were designed around a particular CPU (e.g., an 80286), and were designed to accommodate a dedicated floating point coprocessor (e.g., an 80287), but the coprocessor was not provided with the system. If a user of the system executed the types of applications that could take advantage of the coprocessor, for an additional cost s/he could add the coprocessor to the system.
Thus, while development of the coprocessor enhanced the performance of many CPU based systems, certain design problems arose. The first is that the coprocessor and the general purpose CPU must be tightly integrated, or designed together, to allow them to communicate together effectively. Operationally speaking, the CPU must be able to detect when a program wishes to use the coprocessor, it must pass those instructions over to the coprocessor, it must provide the data to the coprocessor that corresponds to the instructions, and it must be able to receive results back from the coprocessor. In addition, the coprocessor must know whether the CPU has been interrupted by another process, and whether it still requires the result that it is calculating. One skilled in the art will appreciate that many other issues arise relating to communications that must occur between a CPU and a coprocessor. Consequently, since the CPU and the coprocessor have to be so tightly integrated, most coprocessors that have been designed are typically designed to work with a particular CPU.
A problem that stems from the tight integration that is required between a CPU and coprocessor is that enhancement of the design of a particular CPU often requires a corresponding enhancement (or change) in the design of its associated coprocessor. For instance, an older coprocessor will typically not function with a newer CPU, and a newer coprocessor will typically not function with an older CPU. Thus, every time a CPU manufacturer wishes to introduce a new CPU, they must decide whether they want to develop a dedicated coprocessor that will work along with it. A decision to develop a coprocessor is a very costly decision that ultimately must be supported by the marketplace.
In addition, although the above-described history of the floating-point coprocessor provides a basis for understanding that the coprocessor must be designed with a specific CPU in mind, it does not address the scope of today's coprocessing problems. Certain present day application programs require complex, time-consuming calculations that are neither appropriate for a CPU, nor for a floating-point coprocessor; i.e., other types of coprocessor's are required to optimally execute these application programs. Such programs perform 3-D rendering for graphics applications, audio/signal processing etc. But graphics coprocessors, audio coprocessors, etc., that are required to perform these special-purpose programs typically must provide a particular interface (e.g., AGP) and thus these coprocessors will only inter-operate with CPU's that are designed for that particular interface as well.
From the viewpoint of a system designer, choosing a particular CPU for a particular application is increasingly difficult. The designer must anticipate the future needs of the system, utilizing tightly coupled CPU/coprocessor products, without being able to select the CPU and its coprocessors separate from one another. For example, a designer may have requirements within an application that may be satisfied by choosing a relatively simple CPU along with a fairly complex graphics coprocessor. Regrettably, the complex coprocessor today is only compatible with an equally complex (and costly) CPU. Alternatively, the designer may have requirements within an application that may be satisfied by selecting a complex CPU along with a simple coprocessor. This combination is unfortunately not possible either because the complex CPU only interfaces to an equally complex (and costly) coprocessor.
Therefore, what is needed is a configurable coprocessor interface that allows a variety of CPU's to be easily coupled to a variety of different coprocessors, without requiring that the coprocessors be designed specifically for those CPU's.
What is also needed is a configurable coprocessor interface that allows both forward and backward compatibility between CPU's and coprocessors. That is, a coprocessor interface is desired that allows older, or legacy, coprocessors to be utilized with newer CPU's, and vice versa.
Further, what is needed is a “standardized” coprocessor interface for which CPU's and coprocessors can be designed. Such an interface would allow a system designer to select those specific CPU and coprocessor combinations that provide an optimum solution for the designer's needs, without regard to proprietary interface requirements.
Finally, what is needed is a coprocessor interface that takes advantage of modern processing technology, such as multiple-issue of instructions, out-of-order data transfer, etc., without mandating that such technology exist in every device on the interface.